#ifndef __CALLBACK_H_
#define __CALLBACK_H_

#define CALLBACK_MAKE_TEMPLATE_PARAMS

#define CALLBACK_JOIN(a, b) a##b

#define CALLBACK_MAKE_PARAMS_0(t)
#define CALLBACK_MAKE_PARAMS_1(t)	t##1
#define CALLBACK_MAKE_PARAMS_2(t)	t##1, t##2
#define CALLBACK_MAKE_PARAMS_3(t)	t##1, t##2, t##3
#define CALLBACK_MAKE_PARAMS_4(t)	t##1, t##2, t##3, t##4
#define CALLBACK_MAKE_PARAMS_5(t)	t##1, t##2, t##3, t##4, t##5
#define CALLBACK_MAKE_PARAMS_6(t)	t##1, t##2, t##3, t##4, t##5, t##6
#define CALLBACK_MAKE_PARAMS_7(t)	t##1, t##2, t##3, t##4, t##5, t##6, t ##7

#define CALLBACK_MAKE_FUNC_PARAMS_0( t , a )
#define CALLBACK_MAKE_FUNC_PARAMS_1( t , a )	t##1 a##1
#define CALLBACK_MAKE_FUNC_PARAMS_2( t , a )	t##1 a##1, t##2 a##2
#define CALLBACK_MAKE_FUNC_PARAMS_3( t , a )	t##1 a##1, t##2 a##2, t##3 a##3
#define CALLBACK_MAKE_FUNC_PARAMS_4( t , a )	t##1 a##1, t##2 a##2, t##3 a##3, t##4 a##4
#define CALLBACK_MAKE_FUNC_PARAMS_5( t , a )	t##1 a##1, t##2 a##2, t##3 a##3, t##4 a##4, t##5 a##5
#define CALLBACK_MAKE_FUNC_PARAMS_6( t , a )	t##1 a##1, t##2 a##2, t##3 a##3, t##4 a##4, t##5 a##5, t##6 a##6
#define CALLBACK_MAKE_FUNC_PARAMS_7( t , a )	t##1 a##1, t##2 a##2, t##3 a##3, t##4 a##4, t##5 a##5, t##6 a##6, t##7 a##7

#define CALLBACK_MAKE_VARS_0( t , a )
#define CALLBACK_MAKE_VARS_1( t , a )		t##1 a##1
#define CALLBACK_MAKE_VARS_2( t , a )		t##1 a##1; t##2 a##2
#define CALLBACK_MAKE_VARS_3( t , a )		t##1 a##1; t##2 a##2; t##3 a##3
#define CALLBACK_MAKE_VARS_4( t , a )		t##1 a##1; t##2 a##2; t##3 a##3; t##4 a##4
#define CALLBACK_MAKE_VARS_5( t , a )		t##1 a##1; t##2 a##2; t##3 a##3; t##4 a##4; t##5 a##5
#define CALLBACK_MAKE_VARS_6( t , a )		t##1 a##1; t##2 a##2; t##3 a##3; t##4 a##4; t##5 a##5; t##6 a##6
#define CALLBACK_MAKE_VARS_7( t , a )		t##1 a##1; t##2 a##2; t##3 a##3; t##4 a##4; t##5 a##5; t##6 a##6; t##7 a##7

#define CALLBACK_MAKE_VARS_STRUCTURE_0( t , a )
#define CALLBACK_MAKE_VARS_STRUCTURE_1( t , a )		t##1 ( a##1 )
#define CALLBACK_MAKE_VARS_STRUCTURE_2( t , a )		t##1 ( a##1 ), t##2 ( a##2 )
#define CALLBACK_MAKE_VARS_STRUCTURE_3( t , a )		t##1 ( a##1 ), t##2 ( a##2 ), t##3 ( a##3 )
#define CALLBACK_MAKE_VARS_STRUCTURE_4( t , a )		t##1 ( a##1 ), t##2 ( a##2 ), t##3 ( a##3 ), t##4 ( a##4 )
#define CALLBACK_MAKE_VARS_STRUCTURE_5( t , a )		t##1 ( a##1 ), t##2 ( a##2 ), t##3 ( a##3 ), t##4 ( a##4 ), t##5 ( a##5 )
#define CALLBACK_MAKE_VARS_STRUCTURE_6( t , a )		t##1 ( a##1 ), t##2 ( a##2 ), t##3 ( a##3 ), t##4 ( a##4 ), t##5 ( a##5 ), t##6 ( a##6 )
#define CALLBACK_MAKE_VARS_STRUCTURE_7( t , a )		t##1 ( a##1 ), t##2 ( a##2 ), t##3 ( a##3 ), t##4 ( a##4 ), t##5 ( a##5 ), t##6 ( a##6 ), t##7 ( a##7 )

#define CALLBACK_MAKE_VARS_ASSIGN_0( t , a )
#define CALLBACK_MAKE_VARS_ASSIGN_1( t , a )		t##1 = a##1
#define CALLBACK_MAKE_VARS_ASSIGN_2( t , a )		t##1 = a##1; t##2 = a##2
#define CALLBACK_MAKE_VARS_ASSIGN_3( t , a )		t##1 = a##1; t##2 = a##2; t##3 = a##3
#define CALLBACK_MAKE_VARS_ASSIGN_4( t , a )		t##1 = a##1; t##2 = a##2; t##3 = a##3; t##4 = a##4
#define CALLBACK_MAKE_VARS_ASSIGN_5( t , a )		t##1 = a##1; t##2 = a##2; t##3 = a##3; t##4 = a##4; t##5 = a##5
#define CALLBACK_MAKE_VARS_ASSIGN_6( t , a )		t##1 = a##1; t##2 = a##2; t##3 = a##3; t##4 = a##4; t##5 = a##5; t##6 = a##6
#define CALLBACK_MAKE_VARS_ASSIGN_7( t , a )		t##1 = a##1; t##2 = a##2; t##3 = a##3; t##4 = a##4; t##5 = a##5; t##6 = a##6; t##7 = a##7


#define CALLBACK_MAKE_PARAMS(n, t)  CALLBACK_JOIN(CALLBACK_MAKE_PARAMS_, n)(t)
#define CALLBACK_MAKE_FUNC_PARAMS( n, t, a ) CALLBACK_JOIN(CALLBACK_MAKE_FUNC_PARAMS_, n)(t, a )
#define CALLBACK_MAKE_VARS( n, t, a )	CALLBACK_JOIN(CALLBACK_MAKE_VARS_, n)( t, a )
#define CALLBACK_MAKE_VARS_STRUCTURE( n, t, a )	CALLBACK_JOIN(CALLBACK_MAKE_VARS_STRUCTURE_, n)( t, a )
#define CALLBACK_MAKE_VARS_ASSIGN( n, t, a )	CALLBACK_JOIN(CALLBACK_MAKE_VARS_ASSIGN_, n)( t, a )

namespace share
{

template <class TSignature>
class Callback;

template <class TSignature>
class Callbacker;

}

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 0
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 1
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 2
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 3
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 4
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 5
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 6
#include "callback_template.h"

#undef CALLBACK_PARAMS_NUM
#define CALLBACK_PARAMS_NUM 7
#include "callback_template.h"



#endif // __CALLBACK_H_
